package ru.myrtle.umf.impl;

import java.util.*;
import ru.myrtle.umf.*;
import ru.myrtle.umf.util.*;

public class UClassifierOperations extends UClassifierOperationsStub  {

    private static final Boolean DEFAULT_BOOLEAN = Boolean.FALSE;
    private static final Integer DELAULT_INTEGER = 0;
    private static final Float DEFAULT_FLOAT = 0.0F;
    private static final Double DEFAULT_DOUBLE = 0.0;
    private static final Long DEFAULT_LONG = (long) 0;
    private static final Short DEFAULT_SHORT = (short) 0;
    private static final Byte DEFAULT_BYTE = (byte) 0;
    private static final Character DEFAULT_CHARACTER = '\u0000';
    
    @Override
    public Class getInstanceClass(UClassifier self) {
        String className = self.getInstanceClassName();

        if (className.equals("boolean")) {
            return Boolean.TYPE;
        }
        else if (className.equals("byte")) {
            return Byte.TYPE;
        }
        else if (className.equals("char")) {
            return Character.TYPE;
        }
        else if (className.equals("double")) {
            return Double.TYPE;
        }
        else if (className.equals("float")) {
            return Float.TYPE;
        }
        else if (className.equals("int")) {
            return Integer.TYPE;
        }
        else if (className.equals("long")) {
            return Long.TYPE;
        }
        else if (className.equals("short")) {
            return Short.TYPE;
        }
        else {
            try {
                return Class.forName(
                        self.getInstanceClassName()
                );
            }
            catch (ClassNotFoundException thrown) {
                throw new RuntimeException(thrown); // todo
            }
        }
    }

    @Override
    public boolean isSetInstanceClass(UClassifier self) {
        return true;
    }

    @Override
    public void setInstanceClass(UClassifier self, Class _instanceClass_) {
        self.setInstanceClassName(
                _instanceClass_.getName()
        );
    }

    @Override
    public void unsetInstanceClass(UClassifier self) {
    }

    @Override
    public String getInstanceTypeName(UClassifier self) {
        return self.getInstanceClassName();
    }

    @Override
    public boolean isSetInstanceTypeName(UClassifier self) {
        return true;
    }

    @Override
    public void setInstanceTypeName(UClassifier self, String _instanceTypeName_) {
        self.setInstanceClassName(_instanceTypeName_);
    }

    @Override
    public void unsetInstanceTypeName(UClassifier self) {
    }

    @Override
    public Object getDefaultValue(UClassifier self) {
        Class<?> instanceClass = null;
        try {
            instanceClass = self.getInstanceClass();
        }
        catch (Exception e) {
            // Continue with no instanceClass.
        }

        Object defaultValue = null;

        if (instanceClass != null && instanceClass.isPrimitive()) {
            if (instanceClass == Boolean.TYPE) {
                defaultValue = DEFAULT_BOOLEAN;
            }
            else if (instanceClass == Integer.TYPE) {
                defaultValue = DELAULT_INTEGER;
            }
            else if (instanceClass == Float.TYPE) {
                defaultValue = DEFAULT_FLOAT;
            }
            else if (instanceClass == Double.TYPE) {
                defaultValue = DEFAULT_DOUBLE;
            }
            else if (instanceClass == Long.TYPE) {
                defaultValue = DEFAULT_LONG;
            }
            else if (instanceClass == Short.TYPE) {
                defaultValue = DEFAULT_SHORT;
            }
            else if (instanceClass == Byte.TYPE) {
                defaultValue = DEFAULT_BYTE;
            }
            else if (instanceClass == Character.TYPE) {
                defaultValue = DEFAULT_CHARACTER;
            }
        }

        return defaultValue;
    }

    @Override
    public boolean isSetDefaultValue(UClassifier self) {
        return true;
    }

    @Override
    public boolean isInstance(UClassifier self, Object object) {
        return self.getInstanceClass().isInstance(object);
    }

}
